/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.pg.misra.Helpers;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.openide.util.Exceptions;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import pl.pg.misra.AST.AST;
import pl.pg.misra.Interfaces.IRuleChecker;

/**
 *
 * @author Paweł
 */
public class RuleChecker implements IRuleChecker {
    private List<AST> asts;
    
    @Override
    public List<String> checkRules(List<AST> asts) {
        List<String> result = new ArrayList<>();
        List<String> rules = new ArrayList<>();
        
        this.asts = asts;
        
        try {
            rules = getEnabledRules();

        } catch (ParserConfigurationException | SAXException | IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        
        for (String rule : rules){
            try {
                result.addAll(loadRule(rule));
            } catch (            ClassNotFoundException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
        
        return result;
    }
    
    private List<String> loadRule(String ruleName) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
        List<String> result;
        
        Class ruleClass = Class.forName(ruleName) ;
        
        Object ruleInstance = ruleClass.newInstance();
        
        Method checkRule = ruleClass.getMethod("checkRule", List.class);
        
        result = (List<String>) checkRule.invoke(ruleInstance, asts);
        
        return result;
    }
    
    private List<String> getEnabledRules() throws ParserConfigurationException, SAXException, IOException{
        List<String> result = new ArrayList<>();
        
        Node rule;
        Element ruleElement;

        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
        Document doc = docBuilder.parse (new File("config.xml"));
        
        doc.getDocumentElement().normalize();
        
        NodeList listOfRules = doc.getElementsByTagName("rule");
        
        for (int index = 0; index < listOfRules.getLength(); index++){
            rule = listOfRules.item(index);
            
            if (rule.getNodeType() == Node.ELEMENT_NODE){
                ruleElement = (Element) rule;

                if (Boolean.parseBoolean(ruleElement.getElementsByTagName("enabled").item(0).getFirstChild().getNodeValue())){
                    result.add(ruleElement.getElementsByTagName("className").item(0).getFirstChild().getNodeValue());
                }
            }
        }
        
        return result;
    }
}
